<script setup lang="ts">
defineOptions({
  name: "switchTableTabs"
});

import { ref, computed, useSlots, onMounted, onUnmounted, nextTick } from "vue";
import ReSegmented, { type OptionsType } from "@/components/ReSegmented";
import { useUpdateDomHeight, useCancelUpdateDomHeight } from "@/hooks/useCommon";
import { PxScrollbar } from "px-ui";
import { useElementSize } from "@vueuse/core";

const switchTableTabsRef = ref<HTMLElement | null>(null);
const { height } = useElementSize(switchTableTabsRef);
const defaultScrollbarHeight = computed(() => height.value - 40 - 16);

// switchTableTabs 模式： 默认 default   自适应 self-adapt
type switchTableTabsType = "default" | "self-adapt";

const props = defineProps({
  options: {
    type: Array as PropType<Array<OptionsType>>,
    default: () => []
  },
  boxShadow: {
    type: Boolean,
    default: true
  },
  gap: {
    type: Number,
    default: 18
  },
  defaultHeight: {
    type: Number,
    default: 740
  },
  loading: {
    type: Boolean,
    default: false
  },
  type: {
    type: String as PropType<switchTableTabsType>,
    default: "default"
  }
});

const realDefaultHeight = computed(() => props.defaultHeight || defaultScrollbarHeight.value);

const scrollbarRef = ref<InstanceType<typeof PxScrollbar>>();
const slots = useSlots();
const switchTabsContentRef = ref(null);
const switchTabsContentHeight = ref<number>(realDefaultHeight.value);
const activeTab = defineModel({ type: Number, default: 0 });
const activeCom = computed(() => props.options[activeTab.value].com);
const comProps = computed(() => props.options[activeTab.value]?.props);

const tabKey = ref<string>(Math.random().toString(36).slice(2, 10));

const emits = defineEmits(["before-change"]);

const switchTabsChangeHandler = async () =>
  await useUpdateDomHeight(switchTabsContentHeight, switchTabsContentRef, props.gap, realDefaultHeight.value);

const changeHandler = async () => {
  await switchTabsChangeHandler();
  await nextTick();
  scrollbarRef.value?.setScrollTop(0);
  scrollbarRef.value?.update();
};

const beforeChangeHandler = () => {
  emits("before-change");
};

const updateCurrentTab = () => {
  tabKey.value = Math.random().toString(36).slice(2, 10);
};

onMounted(async () => {
  await switchTabsChangeHandler();
});

onUnmounted(() => useCancelUpdateDomHeight());

defineExpose({
  updateCurrentTab
});
</script>

<template>
  <div ref="switchTableTabsRef" class="switchTableTabs-overview">
    <div v-if="options.length > 1" class="tabs">
      <ReSegmented v-model="activeTab" :options="options" :boxShadow="boxShadow" @change="changeHandler" @before-change="beforeChangeHandler" />
      <div v-if="slots?.default" class="tabs-slot"><slot /></div>
    </div>
    <div ref="switchTabsContentRef" v-loading="loading" :class="['content', type === 'self-adapt' ? 'content-self-adapt' : '']">
      <px-scrollbar ref="scrollbarRef" :max-height="switchTabsContentHeight">
        <transition name="fab-tabs-fade" mode="out-in">
          <component :is="activeCom" :key="tabKey" :height="`${switchTabsContentHeight}px`" v-bind="{ ...comProps }" />
        </transition>
      </px-scrollbar>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.switchTableTabs-overview {
  display: flex;
  flex-direction: column;
  gap: 16px;
  height: 100%;

  .tabs {
    display: flex;
    gap: 16px;
    align-items: center;
    justify-content: space-between;
    width: 100%;
  }

  .content {
    box-sizing: border-box;
    // height: 0;
    // flex: 1;
    // height: fit-content;
    width: 100%;

    .px-scrollbar {
      width: 100%;

      :deep(.px-scrollbar__view) {
        height: 100%;
      }

      .fab-tabs-fade-enter-active,
      .fab-tabs-fade-leave-active {
        transition: all 0.4s ease;
      }

      .fab-tabs-fade-enter-from {
        opacity: 0;
        transform: translateX(-80px);
      }

      .fab-tabs-fade-leave-to {
        opacity: 0;
        transform: translateX(80px);
      }
    }
  }

  .content-self-adapt {
    flex: 1;
    height: 0;
  }
}
</style>
